import {Controller, HttpGetReq, idReq} from "../type/interfaces.ts";
import { handle } from "../vendor/handle.ts";
import {IpcMainEvent,} from "electron";
import axios from "axios";
import {electronStore} from "../vendor/electron-store.js";
import {mainWindow} from "../windows/main-window.js";
import {electronLogger} from "../vendor/electron-logger.js";


export default class RequestController implements Controller {

  private loadingMap = new Map<number, AbortController>();


  @handle()
  async httpGet(e: IpcMainEvent, req: HttpGetReq)  {
    try {
      const data = await axios.get(req.url, {
        headers: req.header,
        proxy: electronStore.getAxiosProxy(),
      });
      return data.data
    } catch (error) {
      if (axios.isAxiosError(error)) {
        console.log("AxiosError", error.message)
      } else {
        console.log("httpGet err", error)
      }
      throw error;
    }
  }

  @handle()
  async getStream(e: IpcMainEvent, req: HttpGetReq): Promise<any> {
    if (req.id === undefined) return
    const controller = new AbortController();
    this.loadingMap.set(req.id, controller)
    const header = req.header
    try {

      // console.log("流请求头", header, video.url)
      const response = await axios({
        method: 'get',
        url: req.url,
        responseType: 'stream',
        proxy: electronStore.getAxiosProxy(),
        headers: header,
        signal: controller.signal
      });

      response.data.on('data', (chunk: Uint8Array) => {
        mainWindow.send('stream-progress', {
          data: chunk,
          id: req.id
        });
      });

      response.data.on('end', () => {
        this.loadingMap.delete(<number>req.id)
        mainWindow.send('stream-complete', {
          id: req.id,
        });
      });

      response.data.on('error', (err: any) => {
        this.loadingMap.delete(<number>req.id)
        electronLogger.info("流error", err.messager, err.name)
        if (axios.isCancel(err)) {
          console.log('Download canceled1');
        }
      });

    } catch (error: any) {
      this.loadingMap.delete(req.id)
      if (axios.isCancel(error)) {
        console.log('Download canceled');
        return
      }
      console.error('Error downloading file:', error.code, error.message);
      mainWindow.send('stream-error', {
        data: error.code,
        header: header,
        id: req.id
      });
    }
  }

  @handle()
  async abortStream(e: IpcMainEvent, req: idReq) {
    return this.loadingMap.get(req.id)?.abort()
  }

}

export const requestController = new RequestController()
